#include <algorithm>

#include "EventManager.hpp"

namespace fge
{

EventManager::EventManager()
{
}

EventManager::~EventManager()
{
}

void EventManager::Register(uint32_t eventId, IEventReceiver *receiver)
{
	std::map<uint32_t, std::vector<IEventReceiver*> >::iterator mapIterator = receivers.find(eventId);

	if(mapIterator == receivers.end())
	{
		receivers[eventId] = std::vector<IEventReceiver*>();
		receivers[eventId].push_back(receiver);
	}
	else
	{
		bool foundIt = false;

		for(std::vector<IEventReceiver*>::iterator receiverIterator = mapIterator->second.begin();
			receiverIterator != mapIterator->second.end(); ++receiverIterator)
		{
			if(*receiverIterator == receiver)
			{
				foundIt = true;
				break;
			}
		}
		if(!foundIt)
		{
			mapIterator->second.push_back(receiver);
		}
	}
}

void EventManager::Unregister(uint32_t eventId, IEventReceiver *receiver)
{
	std::map<uint32_t, std::vector<IEventReceiver*> >::iterator mapIterator = receivers.find(eventId);

	if(mapIterator != receivers.end())
	{
		for(std::vector<IEventReceiver*>::iterator receiverIterator = mapIterator->second.begin();
			receiverIterator != mapIterator->second.end(); ++receiverIterator)
		{
			if(*receiverIterator == receiver)
			{
				mapIterator->second.erase(receiverIterator);
				break;
			}
		}
	}
}

void EventManager::UnregisterAll(IEventReceiver *receiver)
{
	for(std::map<uint32_t, std::vector<IEventReceiver*> >::iterator mapIterator = receivers.begin();
		mapIterator != receivers.end(); ++mapIterator)
	{
		for(std::vector<IEventReceiver*>::iterator receiverIterator = mapIterator->second.begin();
			receiverIterator != mapIterator->second.end(); ++receiverIterator)
		{
			if(*receiverIterator == receiver)
			{
				mapIterator->second.erase(receiverIterator);
				break;
			}
		}
	}
}

void EventManager::AddEvent(const Event &event)
{
	eventsToAdd.push_back(event);
}

void EventManager::ProcessEvents()
{
	events.insert(events.end(), eventsToAdd.begin(), eventsToAdd.end());
	eventsToAdd.clear();

	std::map<uint32_t, std::vector<IEventReceiver*> >::iterator mapIterator = receivers.begin(); 
	while(mapIterator != receivers.end())
	{
		if(mapIterator->second.size() == 0)
			receivers.erase(mapIterator++);
		else
			++mapIterator;
	}

	for(std::vector<Event>::iterator eventIterator = events.begin();
		eventIterator != events.end(); ++eventIterator)
	{
		std::map<uint32_t, std::vector<IEventReceiver*> >::iterator mapIterator = receivers.find(eventIterator->id);
		if(mapIterator != receivers.end())
		{
			for(std::vector<IEventReceiver*>::iterator receiverIterator = mapIterator->second.begin();
				receiverIterator != mapIterator->second.end(); ++receiverIterator)
			{
				(*receiverIterator)->ReceiveEvent(*eventIterator);
			}
		}
	}

	events.clear();
}

}
